{*******************************************************************************
* The contents of this file are used with permission, subject to the Mozilla   *
* Public License Version 1.1 (the "License"); you may not use this file except *
* in compliance with the License. You may obtain a copy of the License at      *
* http://www.mozilla.org/MPL/                                                  *
*                                                                              *
* Software distributed under the License is distributed on an "AS IS" basis,   *
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for *
* the specific language governing rights and limitations under the License.    *
*                                                                              *
* The Original Code is distributed as part of the "mediate" product and is     *
* Copyright (C) @home media limited. All Rights Reserved.                      *
*                                                                              *
* Email: support@athomemedia.co.uk                                             *
* Web:   http://www.athomemedia.co.uk                                          *
*******************************************************************************}

unit DesignerLanguage;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ImgList, PngImageList, ComCtrls, ExtCtrls, StdCtrls, UIObjects,
  Languages, ActnList;

type
  TfrmLanguage = class(TForm)
    pbHeader: TPaintBox;
    lbCaption: TLabel;
    lbAction: TLabel;
    btClose: TButton;
    ActionList1: TActionList;
    acAdd: TAction;
    acRemove: TAction;
    pnListItems: TPanel;
    Bevel1: TBevel;
    Bevel3: TBevel;
    lvItems: TListView;
    btAdd: TButton;
    btRemove: TButton;
    btEdit: TButton;
    acEdit: TAction;
    procedure lvItemsAdvancedCustomDrawItem(Sender: TCustomListView;
      Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
      var DefaultDraw: Boolean);
    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure pbHeaderPaint(Sender: TObject);
    procedure acRemoveExecute(Sender: TObject);
    procedure acAddExecute(Sender: TObject);
    procedure lvItemsChange(Sender: TObject; Item: TListItem;
      Change: TItemChange);
    procedure lvItemsDblClick(Sender: TObject);
    procedure acEditExecute(Sender: TObject);
  private
    { Private declarations }
    FHeaderImages: TPngImageList;
    FModified: Boolean;
    FUpdating: Boolean;
    FCurrent: TAHMLanguage;
    FNative: TAHMLanguage;
    function GetSelection: String;
    procedure SetModified(Modified: Boolean);
    procedure ConfigureForm;
    procedure BuildList;
    procedure FocusItem(Focus: Integer);
    procedure FocusText(Name: String);
    procedure UpdateGUIState;
    procedure LoadImages;
  public
    { Public declarations }
    property Current: TAHMLanguage read FCurrent write FCurrent;
    property Native: TAHMLanguage read FNative write FNative;
    property Selection: String read GetSelection;
    property Modified: Boolean read FModified write SetModified;
    class function ShowLanguage(Current, Native: TAHMLanguage): Boolean;
  end;


implementation

{$R *.dfm}

uses Math, Designer, BaseControls, DesignerTextEdit, AHMConsts;

var
  FormInstance: TfrmLanguage;

//-----------------------------------------------------------------------------
//----------------------------- Class Functions -------------------------------
//-----------------------------------------------------------------------------

class function TfrmLanguage.ShowLanguage(Current, Native: TAHMLanguage): Boolean;
begin
  // Set default result - no changes
  Result := False;

  // Create a singleton form instance
  if not Assigned(FormInstance) then
  begin
    FormInstance := TfrmLanguage.Create(Application.MainForm);
    FormInstance.PopupParent := Application.MainForm;
  end;

  FormInstance.Current := Current;
  FormInstance.Native := Native;

  if FormInstance.ShowModal = mrOK then Result := FormInstance.Modified;
end;

//-----------------------------------------------------------------------------
//---------------------------- Property Acessors ------------------------------
//-----------------------------------------------------------------------------

function TfrmLanguage.GetSelection: String;
begin
  if Assigned(lvItems.Selected) then
    Result := lvItems.Selected.Caption
  else
    Result := '';
end;

procedure TfrmLanguage.SetModified(Modified: Boolean);
begin
  FModified := Modified;
  UpdateGUIState;
end;

//-----------------------------------------------------------------------------
//------------------------------- Form Events ---------------------------------
//-----------------------------------------------------------------------------

procedure TfrmLanguage.FormCreate(Sender: TObject);
begin
  // Create and populate PNG image list
  FHeaderImages := TPngImageList.Create(Self);
  LoadImages;
end;

procedure TfrmLanguage.FormShow(Sender: TObject);
begin
  ConfigureForm;
  BuildList;
  UpdateGUIState;
end;

//-----------------------------------------------------------------------------
//------------------------------ Action Events --------------------------------
//-----------------------------------------------------------------------------

procedure TfrmLanguage.acAddExecute(Sender: TObject);
var
  NewName: String;
begin
  // Use editor dialog to create a new text entry
  if TfrmTextProperties.AddText(NewName, FCurrent) then
  begin
    BuildList;
    FocusText(NewName);
    UpdateGUIState;
    Modified := True;
  end;
end;

procedure TfrmLanguage.acEditExecute(Sender: TObject);
var
  NewName: String;
begin
  // Use editor dialog to modify selected text
  NewName := GetSelection;
  if TfrmTextProperties.EditText(NewName, FCurrent) then
  begin
    BuildList;
    FocusText(NewName);
    UpdateGUIState;
    Modified := True;
  end;
end;

procedure TfrmLanguage.acRemoveExecute(Sender: TObject);
var
  Index: Integer;
begin
  // Delete selected entry from current language
  Index := lvItems.Selected.Index;
  if FCurrent.DeleteTranslation(GetSelection) then
  begin
    BuildList;
    FocusItem(Index);
    UpdateGUIState;
    Modified := True;
  end;
end;

//-----------------------------------------------------------------------------
//----------------------------- Control Events --------------------------------
//-----------------------------------------------------------------------------

procedure TfrmLanguage.lvItemsAdvancedCustomDrawItem(Sender: TCustomListView;
  Item: TListItem; State: TCustomDrawState; Stage: TCustomDrawStage;
  var DefaultDraw: Boolean);
begin
  // Render base items in an alternate font to match treeview on main form
  if not (cdsFocused in State) then
    if Item.Data <> nil then
      Sender.Canvas.Font.Color := clActiveCaption;
end;

procedure TfrmLanguage.lvItemsChange(Sender: TObject; Item: TListItem;
  Change: TItemChange);
begin
  // Ignore this event when exiting
  if Application.Terminated then Exit;

  if not FUpdating then UpdateGUIState;
end;

procedure TfrmLanguage.lvItemsDblClick(Sender: TObject);
begin
  // Edit selected list item
  acEdit.Execute;
end;

procedure TfrmLanguage.pbHeaderPaint(Sender: TObject);
begin
  with pbHeader do
  begin
    // Draw background
    Canvas.Brush.Color := clWhite;
    Canvas.FillRect(GetClientRect);
    // Draw appropriate header image
    FHeaderImages.Draw(Canvas, ClientWidth - FHeaderImages.Width, 0, 0);
  end;
end;

//-----------------------------------------------------------------------------
//-------------------------- User Interface Update ----------------------------
//-----------------------------------------------------------------------------

procedure TfrmLanguage.ConfigureForm;
begin
  // Customise display for selected object type
  Caption := 'Edit ' + FCurrent.Name + ' Language';
  lbCaption.Caption := 'Add or remove translations';
  lbAction.Caption := 'You may add, remove or edit the language translations below';

  // Start focus in the list view
  lvItems.SetFocus;
end;

procedure TfrmLanguage.BuildList;
var
  i: Integer;
  BaseItems: Boolean;
begin
  FUpdating := True;
  lvItems.Items.BeginUpdate;
  lvItems.Items.Clear;
  try
    // Determine whether language has a base language defined
    BaseItems := Assigned(FNative.Translations.Parent);

    for i := 0 to Pred(FNative.Translations.Count) do
      with lvItems.Items.Add do
      begin
        Caption := FNative.Translations.Names[i];
        SubItems.Add(FCurrent.Translate(Caption));
        SubItems.Add(FNative.Translations.Values[i]);
        ImageIndex := FNative.ImageIndex + STATE_IMG_ACTIONS;
        if BaseItems then Data := nil
                     else Data := Pointer(1);
      end;

    // Add base descriptor items too if assigned
    if BaseItems then
      for i := 0 to Pred(FNative.Translations.Parent.Count) do
        with lvItems.Items.Add do
        begin
          Caption := FNative.Translations.Parent.Names[i];
          SubItems.Add(FCurrent.Translate(Caption));
          SubItems.Add(FNative.Translations.Parent.Values[i]);
          ImageIndex := FNative.ImageIndex + STATE_IMG_ACTIONS;
          Data := Pointer(1);
        end;
  finally
    lvItems.Items.EndUpdate;
    FUpdating := False;
  end;
end;

procedure TfrmLanguage.FocusItem(Focus: Integer);
begin
  Focus := Min(Focus, lvItems.Items.Count - 1);
  if Focus >= 0 then
  begin
    lvItems.Items[Focus].Selected := True;
    lvItems.Items[Focus].MakeVisible(False);
  end;
end;

procedure TfrmLanguage.FocusText(Name: String);
var
  i: Integer;
begin
  for i := 0 to Pred(lvItems.Items.Count) do
    if lvItems.Items[i].Caption = Name then
    begin
      FocusItem(i);
      Break;
    end;
end;

procedure TfrmLanguage.UpdateGUIState;
begin
  with lvItems do
  begin
    acEdit.Enabled := Assigned(Selected);
    acRemove.Enabled := Assigned(Selected);
  end;
end;

procedure TfrmLanguage.LoadImages;
begin
  with FHeaderImages do
  begin
    Clear;
    Width := 150; Height := 57;

    AddResourcePng('HD_IMG_GENERIC'); //0
  end;

  // Use image lists from main designer form treeview
  with Application.MainForm as TAHMDesignerForm do
  begin
    Self.lvItems.LargeImages := LargeTreeImages;
    Self.lvItems.SmallImages := SmallTreeImages;
  end;
end;

end.
